package com.erebus.controller;


import com.erebus.service.LoggingAdvisor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.client.advisor.PromptChatMemoryAdvisor;
import org.springframework.ai.chat.client.advisor.QuestionAnswerAdvisor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.vectorstore.SearchRequest;
import org.springframework.ai.vectorstore.VectorStore;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.time.LocalDate;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@RestController
@CrossOrigin // 允许跨域
public class OpenAiController {

    private final VectorStore vectorStore;
    ChatClient chatClient;

    public OpenAiController(ChatClient.Builder chatClientBuilder, ChatMemory chatMemory, VectorStore vectorStore) {
        this.chatClient = chatClientBuilder
                // 预设角色
                .defaultSystem("""
                           您是“掏包”网购公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复。
                           您正在通过在线聊天系统与客户互动。
                           在提供有关商品订单的信息之前，您必须始终从用户处获取以下信息：用户id (userId 纯数字的)。
                           在询问用户之前，请检查消息历史记录以获取此信息。
                           在更改预订之前，您必须确保条款允许这样做。
                           如果更改需要收费，您必须在继续之前征得用户同意。
                           使用提供的功能获取购物车信息、下单信息和取消下单。
                           如果需要，可以调用相应函数调用完成辅助动作。
                           请讲中文。
                           今天的日期是 {current_date}.
                        """)
                .defaultAdvisors(
                        new PromptChatMemoryAdvisor(chatMemory), // 提示词聊天对话拦截器
                        new LoggingAdvisor(),  // 自定义拦截器
                        new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults())
                ) // 拦截，修改原内容
                .defaultFunctions("getCart")  // 函数调用
                .build();
        this.vectorStore = vectorStore;
    }

    @GetMapping(value = "/generateStreamAsString", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> generateStreamAsString(@RequestParam(value = "message", defaultValue = "讲个笑话") String message) {


        // 整段输出
//        String content = chatClient.prompt().user(message).call().content();
        // 流式输出
        Flux<String> content = chatClient.prompt().user(message)
                // 动态传入日期
                .system(s -> s.param("current_date", LocalDate.now().toString()))
                .advisors(a -> a.param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 18)) // 存储对话条数 （可选参数）
                .stream().content();

        return content
                .concatWith(Flux.just("[complete]"));
    }
}
